package com.xinchuang.service.targetSystem.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xinchuang.common.Result;
import com.xinchuang.common.ResultUtil;
import com.xinchuang.entity.targetSystem.damage.HurtBasicCorrelation;
import com.xinchuang.entity.targetSystem.target.SystemIndex;
import com.xinchuang.entity.targetSystem.target.TargetSubRelationTable;
import com.xinchuang.mapper.targetSystem.damage.HurtBasicCorrelationMapper;
import com.xinchuang.mapper.targetSystem.target.SystemIndexMapper;
import com.xinchuang.mapper.targetSystem.target.TargetSubRelationTableMapper;
import com.xinchuang.pojoUtil.TargetUtil;
import com.xinchuang.service.RedisUseService;
import com.xinchuang.service.targetSystem.DjNalysisService;
import com.xinchuang.util.FileElseUtil;
import com.xinchuang.util.RedisUtil;
import com.xinchuang.utils.BigdecimalUtil;
import com.xinchuang.utils.RedisName;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class DjNalysisServiceImpl implements DjNalysisService {

    @Resource
    private HurtBasicCorrelationMapper hurtBasicCorrelationMapper;

    @Resource
    private TargetSubRelationTableMapper targetSubRelationTableMapper;

    @Resource
    private SystemIndexMapper systemIndexMapper;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private RedisUseService redisUseService;

    @Override
    public Result getSubTargetHitList(JSONObject jsonObject) {
        String targetId = jsonObject.getString("targetId");
        String subTargetName = jsonObject.getString("subTargetName");
        String subTargetTypeParam = jsonObject.getString("subTargetTypeId");
        String destroyLevel = jsonObject.getString("hsLevelId");
        JSONArray subtargetIdList = jsonObject.getJSONArray("subtargetIdList");
        if (CollectionUtils.isEmpty(subtargetIdList)) {
            subtargetIdList = new JSONArray();
        }

        List<TargetSubRelationTable> targetSubRelationTableList =
                targetSubRelationTableMapper.selectList(
                        new LambdaQueryWrapper<TargetSubRelationTable>()
                                .eq(TargetSubRelationTable::getTargetId,
                                        targetId));
        for (TargetSubRelationTable targetSubRelationTable : targetSubRelationTableList) {
            String subId = targetSubRelationTable.getSubId();
            // 子目标名称
            Object targetName1 = redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + subId, "targetName");
            String targetName;
            if (targetName1 == null) {
                targetName = "";
            } else {
                targetName = targetName1.toString();
            }

            // 子目标类型ID
            String subTargetTypeId = "";
            List subTargetClassifyList = FileElseUtil.getObjectToList(redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + subId, "targetClassify"));
            if (!CollectionUtils.isEmpty(subTargetClassifyList)) {
                subTargetTypeId = subTargetClassifyList.get(subTargetClassifyList.size() - 1).toString();
            }

            // 根据子目标名称筛选
            if (StringUtils.isNotEmpty(subTargetName) && !targetName.contains(subTargetName)) {
                continue;
            }

            // 根据子目标类型筛选
            if (StringUtils.isNotEmpty(subTargetTypeParam)) {
                if (subTargetTypeId.equals(subTargetTypeParam)) {
                    continue;
                }
            }

            // 根据毁伤程度筛选
            if (StringUtils.isNotEmpty(destroyLevel)) {
                List targetClassifyList = FileElseUtil.getObjectToList(redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + targetSubRelationTable.getTargetId(), "targetClassify"));
                if (CollectionUtils.isEmpty(targetClassifyList)) {
                    return ResultUtil.error(500, "目标类型错误");
                } else {
                    List<HurtBasicCorrelation> subTargetByDestroyLevel = hurtBasicCorrelationMapper.getSubTargetByDestroyLevel(targetClassifyList.get(targetClassifyList.size() - 1).toString(), destroyLevel);
                    Set<String> targetTypeSubIdSet = new HashSet<>();
                    for (HurtBasicCorrelation hurtBasicCorrelation : subTargetByDestroyLevel) {
                        targetTypeSubIdSet.add(hurtBasicCorrelation.getTargetTypeSubId());
                    }
                    if (!targetTypeSubIdSet.contains(subTargetTypeId)) {
                        continue;
                    }
                }
            }
            subtargetIdList.add(subId);
        }

        JSONObject djJSONObject = getJsonObject(targetId);

        //表头
        JSONArray index = djJSONObject.getJSONArray("header");
        //表身
        JSONArray dataList = djJSONObject.getJSONArray("dataList");
        final JSONArray subtargetIdListFinal = subtargetIdList;
        JSONArray collect = dataList.stream()
                .map(o -> (JSONObject) o)
                .filter(jsonObject1 -> subtargetIdListFinal.contains(jsonObject1.getString("id")))
                .sorted(Comparator.comparing((JSONObject j) -> j.getDoubleValue("score")).reversed())
                .collect(Collectors.toCollection(JSONArray::new));

        JSONArray table = new JSONArray();
        JSONArray table0 = new JSONArray();
        table0.add("子目标");
        for (int i = 0; i < index.size(); i++) {
            table0.add(index.getString(i));
        }
        table0.add("分值");
        table0.add("排序");
        table.add(table0);

        for (int i = 0; i < collect.size(); i++) {
            JSONObject item = collect.getJSONObject(i);
            JSONArray tableI = new JSONArray();
            tableI.add(item.getString("name"));
            for (int j = 0; j < index.size(); j++) {
                tableI.add(item.getDoubleValue(index.getString(j)));
            }
            double score = item.getDoubleValue("score");
            tableI.add(score);
            tableI.add(i + 1);
            table.add(tableI);
        }

        Map r = new HashMap();
        r.put("tableData", table);
        return ResultUtil.success(r);
    }

    private JSONObject getJsonObject(String targetId) {
        JSONObject djJSONObject;
        if (redisUtil.hasKey(RedisName.DJ_NALYSIS + targetId)) {
            djJSONObject = JSON.parseObject(redisUtil.get(RedisName.DJ_NALYSIS + targetId).toString());
        } else {
            Set<String> index = new HashSet();
            List<JSONObject> jsonArray = new ArrayList<>();
            List<TargetSubRelationTable> targetSubRelationTableList = targetSubRelationTableMapper.selectList(new LambdaQueryWrapper<TargetSubRelationTable>()
                    .eq(TargetSubRelationTable::getTargetId, targetId));
            for (TargetSubRelationTable targetSubRelationTable : targetSubRelationTableList) {
                String subId = targetSubRelationTable.getSubId();
                // 子目标名称
                String targetName = redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + subId, "targetName").toString();

                JSONObject j = new JSONObject();
                j.put("id", subId);
                j.put("name", targetName);

                List<SystemIndex> systemIndexList = systemIndexMapper.selectList(new LambdaQueryWrapper<SystemIndex>()
                        .eq(SystemIndex::getRedId, subId)
                        .eq(SystemIndex::getLevel, "1")
                        .eq(SystemIndex::getType, "ununder")
                );
                double score = 0;
                for (SystemIndex systemIndex : systemIndexList) {
                    String indicatorName = systemIndex.getIndicatorName();
                    String indicatorValue = systemIndex.getIndicatorValue();
                    if (StringUtils.isNotEmpty(indicatorValue)) {
                        score += Double.parseDouble(indicatorValue);
                    }
                    j.put(indicatorName, indicatorValue);
                    index.add(indicatorName);
                }
                j.put("score", score);
                jsonArray.add(j);
            }
            djJSONObject = new JSONObject();
            djJSONObject.put("header", index);
            djJSONObject.put("dataList", jsonArray);
            redisUtil.set(RedisName.DJ_NALYSIS + targetId, djJSONObject.toJSONString(), 1);
        }
        return djJSONObject;
    }

    @Override
    public Result getSubTargetTypeList(JSONObject jsonObject) {
        String targetId = jsonObject.getString("mbId");
        List<TargetSubRelationTable> targetSubRelationTableList = targetSubRelationTableMapper.selectList(new LambdaQueryWrapper<TargetSubRelationTable>()
                .eq(TargetSubRelationTable::getTargetId, targetId));
        HashSet<String> targetClassifySet = new HashSet<>();
        for (TargetSubRelationTable targetSubRelationTable : targetSubRelationTableList) {
            String subId = targetSubRelationTable.getSubId();
            Object targetClassifyObject = redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + subId, "targetClassify");
            if (targetClassifyObject != null) {
                targetClassifySet.add(targetClassifyObject.toString());
            }
        }

        JSONArray jsonArray = new JSONArray();
        for (String targetClassify : targetClassifySet) {
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("value", targetClassify);
            jsonObject1.put("label", redisUseService.getSubTypeName(TargetUtil.getParamListOrString(targetClassify)));
            jsonArray.add(jsonObject1);
        }
        return ResultUtil.success(jsonArray);
    }

    @Override
    public Result getDJResult(JSONObject jsonObject) {
        String targetId = jsonObject.getString("targetId");
        JSONArray tableData = jsonObject.getJSONArray("djList");

        Map<Integer, String> mapName = new HashMap<>();
        Map<Integer, Double> mapScore = new HashMap<>();
        for (int i = 1; i < tableData.getJSONArray(0).size() - 1; i++) {
            mapName.put(i, tableData.getJSONArray(0).getString(i));
            mapScore.put(i, 0D);
        }

        for (int i = 1; i < tableData.size(); i++) {
            JSONArray jsonArray = tableData.getJSONArray(i);
            for (int j = 1; j < jsonArray.size() - 1; j++) {
                mapScore.put(j, mapScore.get(j) + jsonArray.getDoubleValue(j));
            }
        }

        JSONObject djJSONObject = getJsonObject(targetId);
        JSONArray index = djJSONObject.getJSONArray("header");
        JSONArray dataList = djJSONObject.getJSONArray("dataList");
        Map<String, Double> denominatorMap = new HashMap<>();
        for (int i = 0; i < index.size(); i++) {
            denominatorMap.put(index.getString(i), 0D);
        }
        denominatorMap.put("score", 0D);
        for (int i = 0; i < dataList.size(); i++) {
            JSONObject item = dataList.getJSONObject(i);
            for (int j = 0; j < index.size(); j++) {
                String string = index.getString(j);
                denominatorMap.put(string, denominatorMap.get(string) + item.getDoubleValue(string));
            }
            denominatorMap.put("score", denominatorMap.get("score") + item.getDoubleValue("score"));
        }

        JSONArray comAbilities = new JSONArray();
        JSONObject overallAnalysis = new JSONObject();
        for (Map.Entry<Integer, String> entry : mapName.entrySet()) {
            JSONObject j = new JSONObject();
            Integer key = entry.getKey();
            String value = entry.getValue();
            if (value.equals("分值")) {
                Double numerator = mapScore.get(key);
                Double denominator = denominatorMap.get("score");
                double percent;
                if (denominator == 0) {
                    percent = 0;
                } else {
                    percent = numerator / denominator * 100;
                }
                String targetName = redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + targetId, "targetName").toString();
                overallAnalysis.put("label", targetName);
                overallAnalysis.put("value", BigdecimalUtil.doubleTo2DecimalString(percent));
            } else {
                Double numerator = mapScore.get(key);
                Double denominator = denominatorMap.get(value);
                double percent;
                if (denominator == 0) {
                    percent = 0;
                } else {
                    percent = numerator / denominator * 100;
                }
                j.put("label", value);
                j.put("value", BigdecimalUtil.doubleTo2DecimalString(percent));
                comAbilities.add(j);
            }
        }

        Map r = new HashMap();
        r.put("comAbilities", comAbilities);
        r.put("overallAnalysis", overallAnalysis);
        return ResultUtil.success(r);
    }

    @Override
    public Result getSubTargetListByTargetId(JSONObject jsonObject) {
        String targetId = jsonObject.getString("targetId");
        List<TargetSubRelationTable> targetSubRelationTableList = targetSubRelationTableMapper.selectList(new LambdaQueryWrapper<TargetSubRelationTable>()
                .eq(TargetSubRelationTable::getTargetId, targetId));
        JSONArray jsonArray = new JSONArray();
        for (TargetSubRelationTable targetSubRelationTable : targetSubRelationTableList) {
            String subId = targetSubRelationTable.getSubId();
            String targetName = redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + subId, "targetName").toString();
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("value", subId);
            jsonObject1.put("label", targetName);
            jsonArray.add(jsonObject1);
        }
        return ResultUtil.success(jsonArray);
    }
}
